package com.minio.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.minio.config.ComfyUIImg2ImgWithOkHttp;
import com.minio.util.JsonTemplateReader;
import com.minio.util.Response;
import com.minio.util.ResponseResult;
import com.minio.util.StringUtils;
import com.minio.util.file.FileUploadUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Type;
import java.util.*;
import java.util.Map;

@RestController
@RequestMapping(value = "/api/upload")
@Slf4j
@CrossOrigin
public class UploadController {

    @Resource
    private ComfyUIImg2ImgWithOkHttp comfyUIImg2ImgWithOkHttp;

    private static int index = 1;

    private static String workFilePath = "/home/java";
//    private static String workFilePath = "/Users/sangcixiang/Desktop/media/imag";
    @PostMapping("/file")
    public ResponseResult<Object> uploadFile(MultipartFile file,Integer fid) throws IOException, WriterException {
        if (fid != null && fid > 0 && fid < 4){
            index = fid;
        }

        if (file == null) {
            return Response.makeErrRsp("任务执行失败: file is null");
        }

        String client_id = UUID.randomUUID().toString();
        String comfyUIImageName = uploadComfyUIImage(file);
        if (comfyUIImageName == null) {
            return Response.makeErrRsp("任务执行失败: upload file failed");
        } else {
            // 从外部文件读取 JSON 模板
            String jsonTemplatePath = workFilePath + "/comfyWork.json";
            Map<String, String> variables = new HashMap<>();
            variables.put("client_id", client_id);
            variables.put("LoadImage", comfyUIImageName);
            String json = JsonTemplateReader.readTemplateWithVariables(jsonTemplatePath, variables);
            if (json == null) {
                return Response.makeErrRsp("任务执行失败: 无法读取 JSON 模板文件");
            }
            String taskId = comfyUIImg2ImgWithOkHttp.submitImg2ImgTask(json);
            if (taskId == null) {
                return Response.makeErrRsp("任务执行失败: run task failed");
            } else {
                System.out.println("开始任务 [" + taskId + "] ...");
                boolean taskSuccess = comfyUIImg2ImgWithOkHttp.waitForTaskCompletion(taskId, 2000, 1800000L);
                if (!taskSuccess) {
                    return Response.makeErrRsp("任务执行失败: time out");
                } else {
                    JsonObject taskResult = comfyUIImg2ImgWithOkHttp.getTaskStatus(taskId);
                    if (taskResult != null && taskResult.has(taskId)) {
                        String path = UUID.randomUUID().toString().replace("-", "");
                        String name1 = UUID.randomUUID().toString().replace("-", "");
                        String name2 = UUID.randomUUID().toString().replace("-", "");
                        String fileName =  StringUtils.format("/{}/{}/{}", datePath(), path, name1 + ".png");
                        String fileNameQR = StringUtils.format("/{}/{}/{}", datePath(), path, name2 + ".png");

                        saveImage(taskResult, taskId, FileUploadUtils.getDefaultBaseDir() + fileName);
                        merger(fileName, fileNameQR);
                        Map<String, Object> map = new HashMap();
                        map.put("url", "http://img.chat889.cn" + fileName);
                        map.put("qr", "http://img.chat889.cn" + fileNameQR);
                        return Response.makeOKRsp("操作成功").setData(map);
                    } else {
                        return Response.makeErrRsp("任务执行失败: get task status failed");
                    }
                }
            }
        }
    }

    private String uploadComfyUIImage(MultipartFile file) throws IOException {
        String name1 = UUID.randomUUID().toString().replace("-", "");

        BufferedImage bufferedImage = convert(file);

        String fileName = StringUtils.format("/{}/{}/{}", datePath(), "cover", name1 + ".png");
        String toPath = FileUploadUtils.getDefaultBaseDir() + fileName;
        createDir(toPath);
        File newFile = new File(toPath);
        ImageIO.write(bufferedImage, "png",newFile);
        return comfyUIImg2ImgWithOkHttp.uploadFile(newFile, name1 + ".png");

    }

    public BufferedImage convert(MultipartFile multipartFile) throws IOException {
        // 1. 校验文件是否为空
        if (multipartFile.isEmpty()) {
            throw new IOException("上传文件为空，无法转换为 BufferedImage");
        }
        // 2. 获取文件输入流（关键：通过输入流读取图片内容）
        try (InputStream inputStream = multipartFile.getInputStream()) {
            // 3. 用 ImageIO 解析输入流为 BufferedImage
            BufferedImage bufferedImage = ImageIO.read(inputStream);
            // 4. 校验解析结果（若为 null，说明格式不支持）
            if (bufferedImage == null) {
                throw new IOException("不支持的图片格式，文件类型：" + multipartFile.getContentType());
            }
            return crop(bufferedImage);
        }
    }

    private BufferedImage crop(BufferedImage originalImage){
        // 2. 定义裁剪区域（根据实际需求调整参数）
        int width = originalImage.getWidth();
        int height = originalImage.getHeight();
        int newWidth = 940;  // 裁剪宽度
        int newHeight = 710; // 裁剪高度
        int x = (width - newWidth) / 2;      // 左上角X坐标
        int y = (height - newHeight) / 2;       // 左上角Y坐标
        if (x + newWidth > width) {
            x = 0;
            newWidth = width;
        }
        if (y + newHeight > height) {
            y = 0;
            newHeight = height;
        }
        BufferedImage croppedImage = new BufferedImage(newWidth, newHeight, originalImage.getType());
        croppedImage.getGraphics().drawImage(originalImage.getSubimage(x, y, newWidth, newHeight), 0, 0, null);
        return flipHorizontal(croppedImage);
    }

    /**
     * 水平反转图片（左右翻转）
     */
    public BufferedImage flipHorizontal(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage flipped = new BufferedImage(width, height, image.getType());
        for (int y = 0; y < height; y++) {  // 遍历每一行
            for (int x = 0; x < width; x++) {  // 遍历每一列
                // 原始像素位置 (x, y)，反转后位置 (width - 1 - x, y)
                int pixel = image.getRGB(x, y);
                flipped.setRGB(width - 1 - x, y, pixel);
            }
        }
        return flipped;
    }

    private void saveImage(JsonObject taskResult, String taskId, String filePath) {
        JsonObject outputs = taskResult.getAsJsonObject(taskId).getAsJsonObject("outputs");

        for(Map.Entry<String, JsonElement> entry : outputs.entrySet()) {
            JsonObject nodeOutput = ((JsonElement)entry.getValue()).getAsJsonObject();
            if (nodeOutput.has("images")) {
                JsonArray images = nodeOutput.getAsJsonArray("images");
                log.info(images.toString());
                for(int i = 0; i < images.size(); ++i) {
                    JsonObject imageInfo = images.get(i).getAsJsonObject();
                    String filename = imageInfo.get("filename").getAsString();
                    String subfolder = imageInfo.get("subfolder").getAsString();
                    String type = imageInfo.get("type").getAsString();
                    if ("output".equals(type)) {
                        BufferedImage generatedImage = comfyUIImg2ImgWithOkHttp.getGeneratedImage(filename, subfolder, type);
                        if (generatedImage != null) {
                            try {
                                createDir(filePath);
                                ImageIO.write(generatedImage, "png", new File(filePath));
                            } catch (IOException e) {
                                System.err.println("保存图片失败: " + e.getMessage());
                            }
                        }
                    }

                }
            }
        }

    }



    public void merger(String fileName1, String fileName2) throws IOException, WriterException {

        String img2 = workFilePath +"/u"+index+".png";
        index ++;
        if (index > 3){
            index = 1;
        }

        String filePath = FileUploadUtils.getDefaultBaseDir() + fileName1;
        log.info("merger Path {}",FileUploadUtils.getDefaultBaseDir() + filePath);
        BufferedImage image1 = ImageIO.read(new File(filePath));
        BufferedImage image2 = ImageIO.read(new File(img2));
        createDir(filePath);
        int width = image2.getWidth();
        int height = image2.getHeight();
        BufferedImage combined = new BufferedImage(width, height, 1);
        Graphics g = combined.getGraphics();
        g.drawImage(image1, 70, 500, null);
        g.drawImage(image2, 0, 0, null);
        ImageIO.write(combined, "png", new File(filePath));
        BufferedImage image3 = getBufferedImage("http://img.chat889.cn" + fileName1);
        int y1 = height - image3.getHeight();
        int x1 = 0;
        g.drawImage(image3, x1, y1, null);
        String filePath2 = FileUploadUtils.getDefaultBaseDir() + fileName2;
        createDir(filePath2);
        ImageIO.write(combined, "png", new File(filePath2));
    }

    private void createDir(String dir) {
        File file = new File(dir);
        if (file.getParentFile().mkdirs()) {
            System.out.println("目录已成功创建！");
        }
    }

    public String datePath() {
        return FileUploadUtils.datePath();
    }

    //核心代码-生成二维码
    private static BufferedImage getBufferedImage(String content) throws WriterException, IOException {

        String img2 = workFilePath +"/qr_background.png";
        int width = 218;
        int height = 218;
        // 生成二维码
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.MARGIN, 1);

        QRCodeWriter writer = new QRCodeWriter();
        BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

        BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);

        BufferedImage xiangkuang = ImageIO.read(new File(img2));

        BufferedImage combined = new BufferedImage(xiangkuang.getWidth(), xiangkuang.getHeight(), 1);
        Graphics graphics = combined.getGraphics();
        graphics.drawImage(xiangkuang, 0, 0, null);
        graphics.drawImage(image, 307, 49, null);
        graphics.dispose();
        return combined;
    }

}
